package com.smsc.headend.task.engine.handler.impl.deviceconfig;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.map.MapUtil;
import com.smsc.headend.common.enums.PaymentSwithPreToPostOptGroupEnum;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.task.enums.SubTaskStatus;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * (业务实现)
 *
 * @author wjh
 * @date 2022/5/17 17:12.
 */
public class ReadMeterPaymentForSwitchToPostHandler implements TaskHandler {

    private static Long PAYMENT_MODE_POST = 0L;

    @Autowired
    CosemXmlService cosemXmlService;
    @Autowired
    FeignAssetManagementService assetManagementService;
    @Autowired
    TaskDAO taskDAO;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException("device Data type not support");
        }
        CosemData cosemData = (CosemData) deviceData;
        Object data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
        Long value = Convert.toLong(data);
        Map<String, Object> parameterMap = getParameterMap(task, atomicTask);
        Long taskId = MapUtil.getLong(parameterMap, "taskId");
        Boolean taskEnd = isTaskLastAtomicTask(task, atomicTask);
        if (!value.equals(PAYMENT_MODE_POST)) {
            if (atomicTask.getGroupId() == OperationGroup.ReadPaymentMode.getId().intValue()) {
                assetManagementService.updateStepStatusToPost(taskId,task.getTaskNo(), task.getMeterId(), PaymentSwithPreToPostOptGroupEnum.READ_PAYMENT_MODE.getOperationGroup().longValue(), SubTaskStatus.Success.getCode(), null, SystemClock.now() / 1000, null, taskEnd);
            }
            if (atomicTask.getGroupId() == OperationGroup.SwitchPaymentFromPreToPost.getId().intValue()) {
                assetManagementService.updateStepStatusToPost(taskId,task.getTaskNo(), task.getMeterId(), PaymentSwithPreToPostOptGroupEnum.SWITCH_PAYMENT_FROM_PRE_TO_POST.getOperationGroup().longValue(), SubTaskStatus.Failed.getCode(), null, SystemClock.now() / 1000, String.format("handle Switch Meter Payment Mode to Post failed, device mode is [%s]", value), taskEnd);
                return -1;
            }
        } else {
            if (atomicTask.getGroupId() == OperationGroup.ReadPaymentMode.getId().intValue()) {
                assetManagementService.updateStepStatusToPost(taskId,task.getTaskNo(), task.getMeterId(), PaymentSwithPreToPostOptGroupEnum.READ_PAYMENT_MODE.getOperationGroup().longValue(), SubTaskStatus.Success.getCode(), null, SystemClock.now() / 1000, String.format("handle Switch Meter Payment failed, device mode is [%s]", value), taskEnd);
                return -1;
            }
            if (atomicTask.getGroupId() == OperationGroup.SwitchPaymentFromPreToPost.getId().intValue()) {
                assetManagementService.updateStepStatusToPost(taskId,task.getTaskNo(), task.getMeterId(), PaymentSwithPreToPostOptGroupEnum.SWITCH_PAYMENT_FROM_PRE_TO_POST.getOperationGroup().longValue(), SubTaskStatus.Success.getCode(), null, SystemClock.now() / 1000, null, taskEnd
                );
            }
        }
        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        Map<String, Object> parameterMap = getParameterMap(task, atomicTask);
        Long taskId = MapUtil.getLong(parameterMap, "taskId");
        Long step = atomicTask.getGroupId();
        assetManagementService.updateStepStatusToPost(taskId, task.getTaskNo(),task.getMeterId(), step, SubTaskStatus.Failed.getCode(), null, SystemClock.now() / 1000,
                String.format("handle %s fail, [%s]", OperationName.forId(atomicTask.getOperationId()).getName(), message), false);
        return -1;
    }
}
